import { Next, Request, Response } from "restify";
import errors from "restify-errors";

export const requireQuery = (
  requiredQuery: string,
  conditions: ((query: any) => boolean)[] | undefined = undefined,
  required = false,
  defaultValue: any = undefined
) => {
  return (target: any, methodName: string, descriptor: PropertyDescriptor) => {
    const method = descriptor.value;
    descriptor.value = function (
      req: Request,
      res: Response,
      next: Next
    ): void {
      let exist =
        req.query !== undefined && req.query[requiredQuery] !== undefined;

      if (!exist && defaultValue !== undefined) {
        req.query[requiredQuery] = defaultValue;
        exist = true;
      }

      if (!exist && required) {
        next(new errors.MissingParameterError(requiredQuery));

        return;
      }

      if (exist && conditions !== undefined) {
        for (const condition of conditions) {
          if (!condition(req.query[requiredQuery])) {
            next(new errors.InvalidArgumentError(requiredQuery));

            return;
          }
        }
      }

      /* tslint:disable no-invalid-this */
      return method.apply(this, [req, res, next]);
      /* tslint:enable no-invalid-this */
    };
  };
};
